package com.dxl.dao.common.sharding;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;

import org.apache.log4j.Logger;

import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;
import com.google.common.collect.Range;

public class MonthTbShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Date> {
	private static final Logger LOG = Logger.getLogger(MonthTbShardingAlgorithm.class);
	
	public String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Date> shardingValue) {
		LOG.debug(availableTargetNames);
		DateFormat df = new SimpleDateFormat("yyyyMM");
		String month = df.format(shardingValue.getValue());
		for (String availableTargetName : availableTargetNames) {
			if (availableTargetName.endsWith(month)) {
				return availableTargetName;
			}
		}
		throw new IllegalArgumentException();
	}

	public Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Date> shardingValue) {
		LOG.debug(availableTargetNames);
		Collection<String> rst = new LinkedHashSet<String>();
		Collection<Date> values = shardingValue.getValues();
		DateFormat df = new SimpleDateFormat("yyyyMM");
		String month;
		for (Date date : values) {
			month = df.format(date);
			for (String availableTargetName : availableTargetNames) {
				if (availableTargetName.endsWith(month)) {
					rst.add(availableTargetName);
				}
			}
		}
		LOG.debug(rst);
		return rst;
	}

	public Collection<String> doBetweenSharding(Collection<String> availableTargetNames, ShardingValue<Date> shardingValue) {
		LOG.debug(availableTargetNames);
		Collection<String> rst = new LinkedHashSet<String>();
		try {
			Range<Date> values = shardingValue.getValueRange();
			DateFormat df = new SimpleDateFormat("yyyyMM"), dfm = new SimpleDateFormat("yyyyMM");
			Date start = df.parse(df.format(values.lowerEndpoint()));
			Date end = df.parse(df.format(values.upperEndpoint()));
			Calendar c = Calendar.getInstance();
			c.setTime(start);
			String month;
			while (c.getTime().before(end) || c.getTime().equals(end)) {
				month = dfm.format(c.getTime());
				for (String availableTargetName : availableTargetNames) {
					if (availableTargetName.endsWith(month)) {
						rst.add(availableTargetName);
					}
				}
				c.add(Calendar.MONTH, 1);
			}
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		}
		LOG.debug(rst);
		return rst;
	}
}
       